package drone.basis.util ;

import java.math.BigDecimal ;
import java.text.SimpleDateFormat ;
import java.util.Arrays ;
import java.util.Iterator ;
import java.util.LinkedHashSet ;
import java.util.List ;
import java.util.Map ;
import java.util.Objects ;
import java.util.Random ;
import java.util.Set ;
import java.util.UUID ;
import java.util.regex.Pattern ;

import org.apache.commons.lang.CharUtils ;
import org.apache.commons.lang.RandomStringUtils ;

public class StringUtil
{

	public static final String EMPTY = "" ;

	public static final String NULL = null ;

	// GUID
	public static String guid ( )
	{
		return UUID.randomUUID ( ).toString ( ).toUpperCase ( ).replaceAll ( "-" , "" ) ;
	}

	// 随机位数
	public static String number (
			int scale
	)
	{
		return RandomStringUtils.randomNumeric ( scale ) ;
	}

	// 随机字符
	public static String random (
			int scale
	)
	{
		Random random = new Random ( ) ;
		char [ ] codeSequence =
		{
				'A' ,
				'B' ,
				'C' ,
				'D' ,
				'E' ,
				'F' ,
				'0' ,
				'1' ,
				'2' ,
				'3' ,
				'4' ,
				'5' ,
				'6' ,
				'7' ,
				'8' ,
				'9'
		} ;
		StringBuffer buf = new StringBuffer ( ) ;
		buf.append ( codeSequence [ random.nextInt ( 5 ) ] ) ;
		for ( int i = 0 ; i < scale - 1 ; i ++ )
		{
			int index = random.nextInt ( codeSequence.length ) ;
			buf.append ( codeSequence [ index ] ) ;
		}
		return buf.toString ( ) ;
	}

	// 格式化对象避免null的情况
	public static String space (
			Object source
	)
	{
		return ( isEmpty ( source ) ) ? "" : source.toString ( ) ;
	}

	// 括号起指定字符串
	public static String quote (
			Object source
	)
	{
		return ( isEmpty ( source ) ) ? "" : "[" + source.toString ( ) + "]" ;
	}

	// 是否为空
	public static boolean isEmpty (
			Object source
	)
	{
		return ( Objects.isNull ( source ) || source.toString ( ).length ( ) == 0 ) ;
	}

	// 是否整数
	public static boolean isDigit (
			String text
	)
	{
		return RegularUtil.test ( text , RegularUtil.NUM ) ;
	}

	// 是否浮点数
	public static boolean isNumeric (
			String text
	)
	{
		try
		{
			if ( new BigDecimal ( text ).scale ( ) != 2 )
			{
				return false ;
			}
			return true ;
		} catch ( Exception e )
		{
			return false ;
		}
	}

	// 是否是汇率
	public static boolean isRate (
			String text
	)
	{
		try
		{
			if ( new BigDecimal ( text ).scale ( ) != 4 )
			{
				return false ;
			}
			return true ;
		} catch ( Exception e )
		{
			return false ;
		}
	}

	// 是否日期
	public static boolean isDate (
			String text
	)
	{
		try
		{
			new SimpleDateFormat ( "yyyy-MM-dd" ).parse ( text ) ;
			return true ;
		} catch ( Exception e )
		{
			return false ;
		}
	}

	// 填充字符串
	public static String pad (
			String src ,
			int len ,
			char ch ,
			boolean reverse
	)
	{
		int diff = len - src.length ( ) ;
		if ( diff <= 0 )
		{
			return src ;
		}
		char [ ] charr = new char [ len ] ;
		if ( reverse )
		{
			System.arraycopy ( src.toCharArray ( ) , 0 , charr , 0 , src.length ( ) ) ;
			for ( int i = src.length ( ) ; i < len ; i ++ )
			{
				charr [ i ] = ch ;
			}
		} else
		{
			System.arraycopy ( src.toCharArray ( ) , 0 , charr , diff , src.length ( ) ) ;
			for ( int i = 0 ; i < diff ; i ++ )
			{
				charr [ i ] = ch ;
			}
		}
		return new String ( charr ) ;
	}

	// 按照逗号分割字符串
	public static List < String > split (
			String source
	)
	{
		if ( isEmpty ( source ) )
		{
			return null ;
		}
		return Arrays.asList ( source.trim ( ).split ( "," ) ) ;
	}

	// 把新字符串加入数组
	public static String splitCombo (
			String group ,
			String item
	)
	{

		Set < String > set = toSet ( group ) ;
		if ( ! isEmpty ( item ) )
		{
			set.add ( item.trim ( ) ) ;
		}

		return String.join ( "," , set ) ;
	}

	// 把新字符串移除数组
	public static String splitBreak (
			String group ,
			String item
	)
	{

		Set < String > set = toSet ( group ) ;
		if ( ! isEmpty ( item ) )
		{
			set.remove ( item.trim ( ) ) ;
		}

		return String.join ( "," , set ) ;
	}

	// 按照逗号组合
	public static String join (
			List < String > source
	)
	{
		if ( Objects.isNull ( source ) )
		{
			return null ;
		}

		return String.join ( "," , source ) ;
	}

	// 按照逗号分割字符串
	public static Set < String > toSet (
			String source
	)
	{
		if ( isEmpty ( source ) )
		{
			return new LinkedHashSet < String > ( ) ;
		}
		Set < String > set = new LinkedHashSet < String > ( ) ;
		List < String > items = split ( source ) ;
		for ( String item : items )
		{
			if ( ! isEmpty ( item ) )
			{
				set.add ( item.trim ( ) ) ;
			}
		}
		return set ;
	}

	// 字符串反转
	public static String reverse (
			String source
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		String reverse = "" ;
		int length = source.length ( ) ;
		for ( int i = 0 ; i < length ; i ++ )
		{
			reverse = source.charAt ( i ) + reverse ;
		}
		return reverse ;
	}

	// 去空格
	public static String trim (
			String source
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		return source.trim ( ) ;
	}

	// 去换行符
	public static String chomp (
			String source
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}

		if ( source.length ( ) == 1 )
		{
			char ch = source.charAt ( 0 ) ;
			if ( ch == CharUtils.CR || ch == CharUtils.LF )
			{
				return EMPTY ;
			}
			return source ;
		}

		int lastIdx = source.length ( ) - 1 ;
		char last = source.charAt ( lastIdx ) ;

		if ( last == CharUtils.LF )
		{
			if ( source.charAt ( lastIdx - 1 ) == CharUtils.CR )
			{
				lastIdx -- ;
			}
		} else if ( last != CharUtils.CR )
		{
			lastIdx ++ ;
		}
		return source.substring ( 0 , lastIdx ) ;
	}

	// 中间模糊
	public static String fake (
			String source ,
			int top ,
			int end
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		if ( top <= 0 || end <= 0 )
		{
			return source ;
		}
		if ( source.length ( ) < ( top + end ) )
		{
			return source ;
		}
		String theTop = source.substring ( 0 , top ) ;
		String theEnd = source.substring ( source.length ( ) - end , source.length ( ) ) ;
		if ( source.length ( ) > ( top + end ) )
		{
			theTop = pad ( theTop , source.length ( ) - end , '*' , true ) ;
		}
		if ( source.length ( ) == ( top + end ) )
		{
			theTop = theTop + "*" ;
		}
		return theTop + theEnd ;
	}

	// 只保留字符串的中英文和下划线
	public static String concise (
			String source
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		return source.replaceAll ( "[^0-9a-zA-Z\u4e00-\u9fa5_]+" , "" ) ;
	}

	// 去除字符串中的特殊符号
	public static String simple (
			String source
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}

		return Pattern.compile ( RegularUtil.SPECIAL ).matcher ( source ).replaceAll ( "" ) ;
	}

	// 字符串不能超过指定长度
	public static String limit (
			String source ,
			int len
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		if ( source.length ( ) <= len )
		{
			return source ;
		}
		return source.substring ( 0 , len ) + "..." ;
	}

	// 从字符串中某个字符位置截取后半部分
	public static String removeStart (
			String source ,
			String sign
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		int i = source.indexOf ( sign ) ;
		String res = source.substring ( i + 1 , source.length ( ) ) ;
		return res ;
	}

	// 从字符串中某个字符位置截取前半部分
	public static String removeLast (
			String source ,
			String sign
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		int i = source.lastIndexOf ( sign ) ;
		if ( i > 0 )
		{
			return source.substring ( 0 , i ) ;
		} else
		{
			return source ;
		}
	}

	// 从字符串中删除最先出现的指定字符
	public static String deleteTop (
			String source ,
			String sign
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		return source.replaceFirst ( sign , "" ) ;
	}

	// 从字符串中删除最后出现的指定字符
	public static String deleteEnd (
			String source ,
			String sign
	)
	{
		if ( isEmpty ( source ) )
		{
			return source ;
		}
		return reverse ( reverse ( source ).replaceFirst ( sign , "" ) ) ;
	}

	// 将字符串转为下划线分隔
	public static String transferUnder (
			String name
	)
	{
		if ( isEmpty ( name ) )
		{
			return "" ;
		}
		StringBuilder result = new StringBuilder ( ) ;
		result.append ( name.substring ( 0 , 1 ).toLowerCase ( ) ) ;
		for ( int i = 1 ; i < name.length ( ) ; i ++ )
		{
			String s = name.substring ( i , i + 1 ) ;
			String slc = s.toLowerCase ( ) ;
			if ( ! s.equals ( slc ) )
			{
				result.append ( "_" ).append ( slc ) ;
			} else
			{
				result.append ( s ) ;
			}
		}
		return result.toString ( ) ;
	}

	// 将下划线字符串转为驼峰风格
	public static String transferCamel (
			String name
	)
	{
		if ( isEmpty ( name ) )
		{
			return "" ;
		}
		StringBuilder result = new StringBuilder ( ) ;
		for ( int i = 0 ; i < name.length ( ) ; i ++ )
		{
			String s = name.substring ( i , i + 1 ) ;
			if ( s.equals ( "_" ) )
			{
				i ++ ;
				result.append ( name.substring ( i , i + 1 ).toUpperCase ( ) ) ;
			} else
			{
				result.append ( s ) ;
			}
		}
		return result.toString ( ) ;
	}

	// 首字符大写
	public static String upperHead (
			String name
	)
	{
		if ( isEmpty ( name ) )
		{
			return "" ;
		}
		return name.substring ( 0 , 1 ).toUpperCase ( ) + name.substring ( 1 ) ;
	}

	// 首字符小写
	public static String lowerHead (
			String name
	)
	{
		if ( isEmpty ( name ) )
		{
			return "" ;
		}
		return name.substring ( 0 , 1 ).toLowerCase ( ) + name.substring ( 1 ) ;
	}

	public static String listToString (
			List < ? > list
	)
	{
		if ( Objects.isNull ( list ) )
		{
			return "" ;
		}
		StringBuffer sb = new StringBuffer ( ) ;
		Iterator < ? > iter = list.iterator ( ) ;
		while ( iter.hasNext ( ) )
		{
			Object o = iter.next ( ) ;
			if ( ! isEmpty ( o ) )
			{
				sb.append ( "值<" + o.getClass ( ) + "> : " + o.toString ( ) + System.lineSeparator ( ) ) ;
			}
		}
		return sb.toString ( ) ;
	}

	public static String setToString (
			Set < Object > set
	)
	{
		if ( Objects.isNull ( set ) )
		{
			return "" ;
		}
		StringBuffer sb = new StringBuffer ( ) ;
		Iterator < ? > iter = set.iterator ( ) ;
		while ( iter.hasNext ( ) )
		{
			Object o = iter.next ( ) ;
			if ( ! isEmpty ( o ) )
			{
				sb.append ( "值<" + o.getClass ( ) + "> : " + o.toString ( ) + System.lineSeparator ( ) ) ;
			}
		}
		return sb.toString ( ) ;
	}

	public static String mapToString (
			Map < ? , ? > map
	)
	{
		if ( Objects.isNull ( map ) )
		{
			return "" ;
		}
		StringBuffer sb = new StringBuffer ( ) ;
		Iterator < ? > iter = map.entrySet ( ).iterator ( ) ;
		while ( iter.hasNext ( ) )
		{
			Map.Entry < ? , ? > e = ( Map.Entry < ? , ? > ) iter.next ( ) ;
			sb.append ( "键<" + e.getKey ( ).getClass ( ) + "> : " + e.getKey ( ) + System.lineSeparator ( ) ) ;
			if ( Objects.isNull ( e.getValue ( ) ) )
			{
				sb.append ( "值<" + "null" + "> : " + "null" + System.lineSeparator ( ) ) ;
			} else
			{
				sb.append ( "值<" + e.getValue ( ).getClass ( ) + "> : " + e.getValue ( ) + System.lineSeparator ( ) ) ;
			}

		}
		return sb.toString ( ) ;
	}

}
